perm filename APPLY.AX[E81,JMC] blob
sn#607286 filedate 1981-08-19 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 apply.ax[e81,jmc] EKL axioms for apply and eval for making recursive function defs
C00007 ENDMK
C⊗;
apply.ax[e81,jmc] EKL axioms for apply and eval for making recursive function defs
1. We shalll define recursive functions by EKL statements of the form
(DEFINE |append = λu v.apply(APP,<u,v>,appdef)|)
together with
(DEFINE |appdef = (<APP LAMBDA (U V) (IF (NULL U) V (CONS (CAR U) (APP (CDR U) V)))))|).
These are definitions rather than axioms, so they do not allow the user of EKL
to sneak in assumptions as part of his purported function definitions. In fact
we suppose a version of EKL that doesn't allow users to give axioms. Thus EKL
certifies anything proved about the defined functions.
2. We will use the above definitions together with the axiomatization of eval
and apply to prove the equation
∀u v.append(u,v) = if null u then v else car u . append(cdr u,v)
which we have heretofore written as an axiom.
3. Proving that append as defined above satisfies the recursion equation
seems to go better with definitions of apply and eval than have been used
previously, but some of the changes may have other virtues. Some of the
features of these definitions may have been included in other people's
evals.
The functions use an a-list, but instead of consing new pairs on
the front of the a-list, we make a new a-list which has only one occurrence
of the variable. The new function can be called assign and can be defined
assign(var,val,a-list) ← if null a-list then <[var.val]>
else if var = caar a-list then [var.val] . cdr a-list
else car a-list . assign(var,val,cdr a-list).
This version puts a new variable at the end of the a-list, but a version
that puts it on the front can also be given. From our present point of
view, the advantage of assign is that we will finish with the same a-list
with which we start, and this will facilitate proving the recursion
equation. The practical advantage might be that the length of the
a-list won't grow with recursion depth, so that the time
required to look up a variable will depend on the number of variables
and not on recursion depth. The mathematics of assign will be the
same as as that of the a function of (McCarthy and Painter).
4. We have
eval(e,a) ← if atom e then cdr assoc(e,a)
else if car e = IF then
[if evalp(cadr e,a) then eval(caddr e,a) else eval(cadddr e,a)]
else apply(car e,evlis(cdr e,a),a)
apply(fn,args,a) = if fn = CAR then car car args
else if fn = CDR then cdr car args
else if fn = CONS then car args . cadr args
else if atom fn then apply(cdr assoc(fn,a),args,a)
else if caar fn = LAMBDA then
eval(caddr fn,prup(cadr fn,args,a))
prup(vars,args,a) ← if null vars then a
else assign(car vars,car args,prup(cdr vars,cdr args,a))
evalp(p,a) ←
[To be given later, but it is important to note that evalp does not provide
for recursive predicates, which avoids (we hope) an opportunity for
inconsistency].